home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cocktail
/
reuse.lha
/
reuse
/
c
/
Sets.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-18
|
11KB
|
446 lines
/* $Id: Sets.c,v 1.10 1992/05/05 13:19:05 grosch rel $ */
/* $Log: Sets.c,v $
* Revision 1.10 1992/05/05 13:19:05 grosch
* added rcsid
*
* Revision 1.9 1992/03/30 09:53:37 grosch
* fixed bug in IsSubset: removed operator !
*
* Revision 1.8 1992/02/06 09:29:54 grosch
* fixed bug: stdio and ANSI C
*
* Revision 1.7 1992/01/31 16:31:44 grosch
* adaption to ANSI C
*
* Revision 1.6 1991/11/21 14:28:16 grosch
* new version of RCS on SPARC
*
* Revision 1.5 91/07/17 17:23:36 grosch
* introduced ARGS trick for ANSI compatibility
*
* Revision 1.4 90/09/20 09:12:25 grosch
* calmed down lint
*
* Revision 1.3 90/07/04 14:34:02 grosch
* introduced conditional include
*
* Revision 1.2 89/12/08 17:25:01 grosch
* complete redesign in order to increase efficiency
*
* Revision 1.1 89/01/09 17:29:23 grosch
* added functions Size, Minimum, and Maximum
*
* Revision 1.0 88/10/04 11:44:44 grosch
* Initial revision
*
*/
/* Ich, Doktor Josef Grosch, Informatiker, Sept. 1987 */
static char rcsid [] = "$Id: Sets.c,v 1.10 1992/05/05 13:19:05 grosch rel $";
# include "ratc.h"
# include "Sets.h"
# include "DynArray.h"
# include "General.h"
# define BitsPerByte 8
# define BytesPerBitset BitsPerBitset / BitsPerByte
# define ONE 0x80000000
# define NoCard -1
# ifdef PCS10
# define CALL(f) (* f)
# else
# define CALL(f) f
# endif
void MakeSet
# ifdef __STDC__
(tSet * Set, cardinal MaxSize)
# else
(Set, MaxSize)
tSet * Set ;
cardinal MaxSize ;
# endif
{
unsigned long ElmtCount ;
ElmtCount = (MaxSize + BitsPerBitset - (MaxSize & MaskBitsPerBitset)) >> LdBitsPerBitset;
MakeArray ((char * *) & Set->BitsetPtr, & ElmtCount, (unsigned long) BytesPerBitset);
Set->MaxElmt = MaxSize;
Set->LastBitset = ElmtCount - 1;
AssignEmpty (Set);
}
void ReleaseSet (Set)
tSet * Set;
{
unsigned long ElmtCount ;
ElmtCount = Set->LastBitset + 1;
ReleaseArray ((char * *) & Set->BitsetPtr, & ElmtCount, (unsigned long) BytesPerBitset);
}
void Union (Set1, Set2)
tSet * Set1 ;
tSet * Set2 ;
{
register tSet * rSet1 = Set1;
register cardinal i = rSet1->LastBitset + 1;
register BITSET * s1 = rSet1->BitsetPtr;
register BITSET * s2 = Set2->BitsetPtr;
register tSet * rSet2 = Set2;
do {* s1 ++ |= * s2 ++;} while (-- i);
rSet1->Card = NoCard;
rSet1->FirstElmt = Min (rSet1->FirstElmt, rSet2->FirstElmt);
rSet1->LastElmt = Max (rSet1->LastElmt , rSet2->LastElmt );
}
void Difference (Set1, Set2)
tSet * Set1 ;
tSet * Set2 ;
{
register tSet * rSet1 = Set1;
register cardinal i = rSet1->LastBitset + 1;
register BITSET * s1 = rSet1->BitsetPtr;
register BITSET * s2 = Set2->BitsetPtr;
do {* s1 ++ &= ~ * s2 ++;} while (-- i);
rSet1->Card = NoCard;
}
void Intersection (Set1, Set2)
tSet * Set1 ;
tSet * Set2 ;
{
register tSet * rSet1 = Set1;
register cardinal i = rSet1->LastBitset + 1;
register BITSET * s1 = rSet1->BitsetPtr;
register BITSET * s2 = Set2->BitsetPtr;
register tSet * rSet2 = Set2;
do {* s1 ++ &= * s2 ++;} while (-- i);
rSet1->Card = NoCard;
rSet1->FirstElmt = Max (rSet1->FirstElmt, rSet2->FirstElmt);
rSet1->LastElmt = Min (rSet1->LastElmt , rSet2->LastElmt);
}
void SymDiff (Set1, Set2)
tSet * Set1 ;
tSet * Set2 ;
{
register tSet * rSet1 = Set1;
register cardinal i = rSet1->LastBitset + 1;
register BITSET * s1 = rSet1->BitsetPtr;
register BITSET * s2 = Set2->BitsetPtr;
register tSet * rSet2 = Set2;
do {* s1 ++ ^= * s2 ++;} while (-- i);
rSet1->Card = NoCard;
rSet1->FirstElmt = Min (rSet1->FirstElmt, rSet2->FirstElmt);
rSet1->LastElmt = Max (rSet1->LastElmt , rSet2->LastElmt);
}
void Complement (Set)
tSet * Set ;
{
register tSet * rSet = Set;
register cardinal i = rSet->LastBitset;
register BITSET * s1 = rSet->BitsetPtr;
while (i --) {* s1 = ~ * s1; s1 ++;}
* s1 = ((long) ONE >> (rSet->MaxElmt & MaskBitsPerBitset)) & ~ * s1;
if (rSet->Card != NoCard) rSet->Card = (short) rSet->MaxElmt + 1 - rSet->Card;
rSet->FirstElmt = 0;
rSet->LastElmt = rSet->MaxElmt;
}
void Include
# ifdef __STDC__
(tSet * Set, cardinal Elmt)
# else
(Set, Elmt)
tSet * Set ;
cardinal Elmt ;
# endif
{
register tSet * rSet = Set;
register cardinal rElmt = Elmt;
rSet->BitsetPtr [rElmt >> LdBitsPerBitset] |= (unsigned long) ONE >> (rElmt & MaskBitsPerBitset);
rSet->Card = NoCard;
rSet->FirstElmt = Min (rSet->FirstElmt, rElmt);
rSet->LastElmt = Max (rSet->LastElmt , rElmt);
}
void Exclude
# ifdef __STDC__
(tSet * Set, cardinal Elmt)
# else
(Set, Elmt)
tSet * Set ;
cardinal Elmt ;
# endif
{
register tSet * rSet = Set;
register cardinal rElmt = Elmt;
rSet->BitsetPtr [rElmt >> LdBitsPerBitset] &= ~ ((unsigned long) ONE >> (rElmt & MaskBitsPerBitset));
rSet->Card = NoCard;
if (rElmt == rSet->FirstElmt && rElmt < rSet->MaxElmt) rSet->FirstElmt ++;
if (rElmt == rSet->LastElmt && rElmt > 0) rSet->LastElmt --;
}
cardinal Card (Set)
tSet * Set ;
{
register tSet * rSet = Set;
if (rSet->Card == NoCard) {
register cardinal i, n;
register cardinal last = rSet->LastElmt;
n = 0;
for (i = rSet->FirstElmt; i <= last; i ++) {
if (IsElement (i, rSet)) n ++;
}
rSet->Card = n;
}
return rSet->Card;
}
cardinal Minimum (Set)
tSet * Set ;
{
register tSet * rSet = Set;
register cardinal i;
register cardinal last = rSet->LastElmt;
for (i = rSet->FirstElmt; i <= last; i ++) {
if (IsElement (i, rSet)) {
rSet->FirstElmt = i;
return i;
}
}
return 0;
}
cardinal Maximum (Set)
tSet * Set ;
{
register tSet * rSet = Set;
register cardinal i;
register cardinal first = rSet->FirstElmt;
for (i = rSet->LastElmt; i >= first; i --) {
if (IsElement (i, rSet)) {
rSet->LastElmt = i;
return i;
}
}
return 0;
}
cardinal Extract (Set)
tSet * Set ;
{
register cardinal i = Minimum (Set);
Exclude (Set, i);
return i;
}
bool IsSubset (Set1, Set2)
tSet * Set1 ;
tSet * Set2 ;
{
register tSet * rSet1 = Set1;
register cardinal i = rSet1->LastBitset + 1;
register BITSET * s1 = rSet1->BitsetPtr;
register BITSET * s2 = Set2->BitsetPtr;
do {
if (* s1 ++ & ~ * s2 ++) return false;
} while (-- i);
return true;
}
bool IsEqual (Set1, Set2)
tSet * Set1 ;
tSet * Set2 ;
{
register tSet * rSet1 = Set1;
register cardinal i = rSet1->LastBitset + 1;
register BITSET * s1 = rSet1->BitsetPtr;
register BITSET * s2 = Set2->BitsetPtr;
do {
if (* s1 ++ != * s2 ++) return false;
} while (-- i);
return true;
}
bool IsEmpty (Set)
tSet * Set ;
{
register tSet * rSet = Set;
if (rSet->FirstElmt <= rSet->LastElmt) {
register cardinal i = rSet->LastBitset + 1;
register BITSET * s1 = rSet->BitsetPtr;
do {
if (* s1 ++ != 0) return false;
} while (-- i);
}
return true;
}
bool Forall (Set, Proc)
tSet * Set ;
bool (* Proc) ();
{
register tSet * rSet = Set;
register cardinal i;
register cardinal last = rSet->LastElmt;
for (i = rSet->FirstElmt; i <= last; i ++) {
if (IsElement (i, rSet) && ! CALL(Proc) (i)) return false;
}
return true;
}
bool Exists (Set, Proc)
tSet * Set ;
bool (* Proc) ();
{
register tSet * rSet = Set;
register cardinal i;
register cardinal last = rSet->LastElmt;
for (i = rSet->FirstElmt; i <= last; i ++) {
if (IsElement (i, rSet) && CALL(Proc) (i)) return true;
}
return false;
}
bool Exists1 (Set, Proc)
tSet * Set ;
bool (* Proc) ();
{
register tSet * rSet = Set;
register cardinal i, n;
register cardinal last = rSet->LastElmt;
n = 0;
for (i = rSet->FirstElmt; i <= last; i ++) {
if (IsElement (i, rSet) && CALL(Proc) (i)) n ++;
}
return n == 1;
}
void Assign (Set1, Set2)
tSet * Set1 ;
tSet * Set2 ;
{
register tSet * rSet1 = Set1;
register cardinal i = rSet1->LastBitset + 1;
register BITSET * s1 = rSet1->BitsetPtr;
register BITSET * s2 = Set2->BitsetPtr;
register tSet * rSet2 = Set2;
do {* s1 ++ = * s2 ++;} while (-- i);
rSet1->Card = rSet2->Card;
rSet1->FirstElmt = rSet2->FirstElmt;
rSet1->LastElmt = rSet2->LastElmt;
}
void AssignElmt
# ifdef __STDC__
(tSet * Set, cardinal Elmt)
# else
(Set, Elmt)
tSet * Set ;
cardinal Elmt ;
# endif
{
register tSet * rSet = Set;
register cardinal rElmt = Elmt;
AssignEmpty (rSet);
Include (rSet, rElmt);
rSet->Card = 1;
rSet->FirstElmt = rElmt;
rSet->LastElmt = rElmt;
}
void AssignEmpty (Set)
tSet * Set ;
{
register tSet * rSet = Set;
register cardinal i = rSet->LastBitset + 1;
register BITSET * s1 = rSet->BitsetPtr;
do {* s1 ++ = 0;} while (-- i);
rSet->Card = 0;
rSet->FirstElmt = rSet->MaxElmt;
rSet->LastElmt = 0;
}
void ForallDo (Set, Proc)
tSet * Set ;
void (* Proc) ();
{
register tSet * rSet = Set;
register cardinal i;
register cardinal last = rSet->LastElmt;
for (i = rSet->FirstElmt; i <= last; i ++) {
if (IsElement (i, rSet)) CALL(Proc) (i);
}
}
void ReadSet (File, Set)
FILE * File ;
tSet * Set ;
{
register tSet * rSet = Set;
int i, card = 0;
while (fgetc (File) != '{');
AssignEmpty (rSet);
for (;;) {
if (fgetc (File) == '}') break;
(void) fscanf (File, "%d", & i);
Include (rSet, i);
card ++;
}
rSet->Card = card;
}
static FILE * g;
void PrintElmt (Elmt)
cardinal Elmt ;
{
(void) fprintf (g, " %d", Elmt);
}
void WriteSet (File, Set)
FILE * File ;
tSet * Set ;
{
g = File;
(void) fprintf (File, "{");
ForallDo (Set, PrintElmt);
(void) fprintf (File, "}");
}
void InitSets ()
{
if (sizeof (BITSET) != BytesPerBitset)
(void) fprintf (stderr, "Sets: sizeof (BITSET) = %d\n", sizeof (BITSET));
}